<?php
namespace extend\drive;

use \GatewayWorker\Lib\Gateway;
use extend\extend;
use extend\drive\SqlAction;


/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 16-10-24
 * Time: 上午9:22
 */

class action{

    protected static $_instance = null;

    public $client_data = 0;
    /**
     * 构造函数
     */
    public function __construct()
    {
        //$this->Db = extend::db();
        $this->Redis = extend::redis();
        $this->memcache = extend::memcache();
        $this->SqlAction = new SqlAction();
    }

    /**
     * 单例模式
     * @author mmy
     */
    public static function getInstance($host,$port)
    {
        if(self::$_instance === null)
        {
            self::$_instance = new self($host,$port);
        }
        return self::$_instance;
    }

    /**
     * 登录方法
     * @author mmy
     */
    public function login($client_id,$message_data)
    {
        // 判断是否有房间号
        if(!isset($message_data['room_id']))
        {
            throw new \Exception("\$message_data['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
        }

        // 把房间号昵称放到session中
        $room_id = $message_data['room_id'];
        //根据登陆key值获取memcache用户信息
        $userInfo = $this->memcache->getUserInfo($message_data['userKey']);
        $client_name = $userInfo['nickname'];
        $_SESSION['room_id'] = $room_id;
        $_SESSION['client_name'] = $client_name;
        //将用户信息复制到session  备用
        $_SESSION['userInfo'] = array(
            'userid'=>$userInfo['userid'],
            'nickname'=>$userInfo['nickname'],
            'level'=>$userInfo['levelid'],
            'loginlogid'=>$userInfo['loginlogid'],
            'logintime'=>$userInfo['ctime'],
            'ip'=>$userInfo['realIp'],
            'image'=>$userInfo['image'],
            'client_id'=>$client_id,
            'time'=>$userInfo['ctime'],
        );

        $this->bindUid($client_id,$userInfo['userid']);

        //将当前用户加入到用户列表 整合到信息
        Gateway::joinGroup($client_id, $_SESSION['room_id']);

        // 获取房间内所有用户列表
        $clients_list = Gateway::getClientSessionsByGroup($room_id);

        $array = array();
        if(!empty($clients_list))
        {
            foreach($clients_list as $tmp_client_id=>$item)
            {
                $array[ $item['userInfo']['userid']] = $item['userInfo'];
            }
        }
        $array[ $_SESSION['userInfo']['userid']] = $_SESSION['userInfo'];
        print_r($array);
        // 转播给当前房间的所有客户端，xx进入聊天室 message {type:login, client_id:xx, name:xx}
        $new_message = array(
            'type'=>$message_data['type'],
            'client_id'=>$userInfo['userid'],
            'client_name'=>htmlspecialchars($userInfo['nickname']),
            'userid'=>$userInfo['userid'],
            'nickname'=>htmlspecialchars($userInfo['nickname']),
            'time'=>$userInfo['ctime'],
            'ip'=>$userInfo['realIp'],
            'image'=>$userInfo['image'],
            'level'=>$userInfo['levelid'],
            'logintime'=>$userInfo['ctime'],
        );

        Gateway::sendToGroup($room_id, json_encode($new_message));
        $new_message['client_list'] = $array;
        //获取历史消息推送给当前用户 整合到返消息  发送消息
        $message = $this->getRedisChatContent();
        $new_message['history_list'] = $message;
        Gateway::sendToCurrentClient(json_encode($new_message));
    }

    /**
     * 客户端发言
     * @author mmy
     */
    public function say($client_id,$message_data)
    {
        if(!isset($_SESSION['room_id']))
        {
            throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
        }

        //判断用户的状态 禁言，屏蔽，封ip
        $this->judgeUserStatus();


        if($message_data['to_client_id'] != 'all')
        {
            // 私聊
            return $this->privateMessage($client_id,$message_data);

        }
        else
        {
            //群聊
            return $this->groupMessage($client_id,$message_data);
        }

    }

    /**
     * 标志操作
     * @author mmy
     */
    public function status($client_id,$message_data)
    {
        //标志操作
        //echo '111111';
        $res = $Db->execSql("insert into test_user (name,ctime) values ('".$message_data['name']."','".time()."')");
        echo '插入数据库  '.$res;
        // $rest = $redis->push($message_data['userid'],$message_data['name']);
        // echo '-----------------------';
        // print_r($redis->range($message_data['userid']));
        // echo $rest;
    }


    public function logout($client_id)
    {
        // debug
        echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:''\n";
        echo '----------------------';
        echo $_SESSION['room_id'];
        // 从房间的客户端列表中删除
        if(isset($_SESSION['room_id']))
        {
            $room_id = $_SESSION['room_id'];
            $new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
            Gateway::sendToGroup($room_id, json_encode($new_message));
        }
    }

    /**
     * 群聊消息回复
     * @author
     */
    public function groupMessage($client_id,$message_data)
    {
        $room_id = $_SESSION['room_id'];
        $client_name = $_SESSION['client_name'];
        $userinfo = $_SESSION['userInfo'];

        $new_message = array(
            'type'=>'say',
            'from_client_id'=>$userinfo['userid'],
            'from_client_name' =>$userinfo['nickname'],
            'to_client_id'=>'all',
            'content'=>nl2br(htmlspecialchars($message_data['content'])),
            'time'=>date('Y-m-d H:i:s'),
            'image'=>$userinfo['image'],
        );
        //聊天信息推送到redis队列
        $this->saveRedisChatContent($new_message);

        //数据库记录群聊聊天信息
        $this->SqlAction->saveDbChatContent($new_message);
        return Gateway::sendToGroup($room_id ,json_encode($new_message));
    }

    /**
     * 判断用户状态
     * @author mmy
     * @return int
     * 1：禁言，2：封ip
     */
    public function judgeUserStatus()
    {
        $res = $this->SqlAction->judgeUserStatus();
        //有禁言，与封ip记录
        if($res)
        {
            if(is_array($res))
            {
                //推送给当前用户
                $new_message = array(
                    'type'=>'status',
                    'status'=>'forbidip',
                    'forbidType'=>2,
                );
                return Gateway::sendToCurrentClient(json_encode($new_message));
            }

            $new_message = array(
                'type'=>'status',
                'status'=>'forbidip',
                'forbidType'=>$res['type'],
            );
            return Gateway::sendToCurrentClient(json_encode($new_message));
        }
        return ;
    }

    /**
     * 获取客户端远程ip
     * @author mmy
     * @return string
     */
    public function getRemoteIp()
    {
        if (getenv("HTTP_CLIENT_IP"))
            $clientIp = getenv("HTTP_CLIENT_IP");
        else if(getenv("HTTP_X_FORWARDED_FOR"))
            $clientIp = getenv("HTTP_X_FORWARDED_FOR");
        else if(getenv("REMOTE_ADDR"))
            $clientIp = getenv("REMOTE_ADDR");
        else
            $clientIp = "Unknow";

        return $clientIp;
    }



    /**
     * 保存群聊信息到redis
     * @author mmy
     */
    public function saveRedisChatContent($new_message)
    {
        return $this->Redis->push($_SESSION['room_id'],json_encode(array_merge($new_message)),10);
    }

    /**
     * 获取redis聊天队列信息
     * @return mixed
     */
    public function getRedisChatContent()
    {
        return $this->Redis->range($_SESSION['room_id']);
    }

    /**
     * 私聊信息
     * @author mmy
     */
    public function privateMessage($client_id,$message_data)
    {
        $client_name = $_SESSION['client_name'];
        $userInfo = $_SESSION['userInfo'];
        $new_message = array(
            'type'=>'say',
            'from_client_id'=>$userInfo['userid'],
            'from_client_name' =>$userInfo['nickname'],
            'to_client_id'=>$message_data['to_client_id'],
            'content'=>nl2br(htmlspecialchars($message_data['content'])),
            'time'=>date('Y-m-d H:i:s'),
            'image'=>$userInfo['image'],
        );
        $this->sendToClientUid($message_data['to_client_id'],$new_message);
        // Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
        return Gateway::sendToCurrentClient(json_encode($new_message));
    }

    /**
     * 绑定uid到client_id ( 绑定后可用uid发消息)
     *.
     * 参考：http://workerman.net/gatewaydoc/gateway-worker-development/bind-uid.html
     * 参考：http://workerman.net/gatewaydoc/gateway-worker-development/send-to-uid.html
     *
     * @param bool|false $isOnly   是否强制唯一 ( uid可以绑定多个client_id )
     */
    protected function bindUid($client_id = null, $uid = 0, $isOnly = false)
    {
        // 获取当前Uid绑定了几个client_id
        $uidClientData = Gateway::getClientIdByUid($uid);
        if(true === $isOnly && isset($uidClientData[0])){
            // 剔除绑定的client_id
            foreach($uidClientData as $k=>$v){
                Gateway::closeClient($v);
//                Gateway::leaveGroup($v, $this->room_id);
            }
        }

        // 绑定client_id信息
        Gateway::bindUid($client_id, $uid);
    }

    /**
     * 通过Uid发送数据到指定客户端
     *
     * @param $uid              用户ID
     * @param $message array    消息数据
     *
     * @return null             异步发送无返回值
     */
    protected static function sendToClientUid($uid, array $message = [])
    {
        if(0 === self::isUidOnline($uid)) return;
        Gateway::sendToUid($uid, json_encode($message));
    }

    /**
     * 判断uid用户是否在线
     *
     * @param $uid      聊天用户ID
     *
     * @return int      返回值 1：在线   0：不在线
     */
    protected static function isUidOnline($uid)
    {
        return Gateway::isUidOnline($uid);
    }

}